"use strict";
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createListener = void 0;
var http_1 = __importDefault(require("http"));
var https_1 = __importDefault(require("https"));
var path_1 = __importDefault(require("path"));
var querystring_1 = __importDefault(require("querystring"));
var matcher_1 = __importDefault(require("./matcher"));
function createListener(_a) {
    var _b = _a === void 0 ? {} : _a, onData = _b.onData, onError = _b.onError, onEnd = _b.onEnd, onStart = _b.onStart, redirect = _b.redirect;
    return function start(params) {
        if (params === void 0) { params = {}; }
        var data = params.data, url = params.url, options = __rest(params, ["data", "url"]);
        var client = url.startsWith('https://') ? https_1.default : http_1.default;
        var body = typeof data === "object" && Object.keys(data).length ? querystring_1.default.stringify(data) : '';
        var req = client.request(url, __assign(__assign({}, options), { headers: __assign(__assign({ referer: url }, (body ? {
                'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
                accept: 'application/json, text/javascript, */*; q=0.01',
                'accept-language': 'zh-CN,zh;q=0.9',
            } : {})), options.headers) }), function (res) {
            if (res.headers.location) {
                start({
                    url: res.headers.location,
                    headers: {
                        referer: url,
                    }
                });
            }
            else {
                var _a = parseContentType(res.headers["content-type"]), type = _a.type, charset = _a.charset;
                if (charset)
                    res.setEncoding(charset);
                var buf_1 = '';
                if (type === 'text/html') {
                    res.on("data", function (chunk) { return (buf_1 += chunk); });
                    res.on("end", function () {
                        // 解析 html
                        var _a = new matcher_1.default(buf_1).matchIframe().matchVar('ajaxdata').done(), iframe = _a.iframe, ajaxdata = _a.ajaxdata;
                        if (iframe) {
                            var reqOption = {
                                url: joinUrl(url, iframe, true)
                            };
                            start(reqOption);
                        }
                        else if (ajaxdata) {
                            var value = new matcher_1.default(buf_1).matchObject('type').matchObject('url').done();
                            var reqOption = {
                                url: joinUrl(url, value.url),
                                data: {
                                    action: 'downprocess',
                                    sign: ajaxdata,
                                    ves: 1,
                                },
                                method: value.type,
                                headers: {
                                    referer: url,
                                }
                            };
                            start(reqOption);
                        }
                        else /*if (isFinalDownload)*/ {
                            var value = new matcher_1.default(buf_1).matchSecondVerify().matchObject('type').matchObject('url').done();
                            var reqOption = {
                                url: joinUrl(url, value.url, true),
                                method: value.type,
                                data: value.data,
                                headers: {
                                    referer: url,
                                },
                            };
                            start(reqOption);
                        }
                    });
                }
                else if (type === 'text/json') {
                    res.on("data", function (chunk) { return (buf_1 += chunk); });
                    res.on("end", function () {
                        // 1. 预下载，2.最终下载(application/octet-stream)
                        var json = JSON.parse(buf_1);
                        var reqOption = {
                            url: json.dom + "/file/" + json.url,
                            headers: {
                                referer: options.headers.referer,
                            }
                        };
                        if (redirect) {
                            onEnd === null || onEnd === void 0 ? void 0 : onEnd(reqOption.url);
                        }
                        else {
                            start(reqOption);
                        }
                    });
                }
                else if (type === 'application/octet-stream') {
                    // 下载
                    onStart === null || onStart === void 0 ? void 0 : onStart(res.headers);
                    res.on("data", function (chunk) { return onData === null || onData === void 0 ? void 0 : onData(chunk); });
                    res.on("end", function () { return onEnd === null || onEnd === void 0 ? void 0 : onEnd(url); });
                }
                else {
                    onError === null || onError === void 0 ? void 0 : onError("\u627E\u4E0D\u5230 type \u7C7B\u578B\uFF1A" + type);
                }
                res.on("error", function (err) { return onError === null || onError === void 0 ? void 0 : onError(err.message); });
            }
        });
        req.write(body);
        req.end();
    };
}
exports.createListener = createListener;
function parseContentType(contentType) {
    var _a, _b;
    if (contentType === void 0) { contentType = ''; }
    var types = contentType.replace(' ', '').split(';');
    return {
        type: types[0],
        charset: (_b = (_a = types[1]) === null || _a === void 0 ? void 0 : _a.match(/charset=(.*)/)) === null || _b === void 0 ? void 0 : _b[1],
    };
}
function joinUrl(url, pathname, isHttp) {
    if (url === void 0) { url = ''; }
    if (pathname === void 0) { pathname = ''; }
    url = typeof isHttp === "boolean"
        ? isHttp ? url.replace('https://', 'http://') : url.replace('http://', 'https://')
        : url;
    var u = new URL(url);
    return pathname.startsWith('/') ? path_1.default.join(u.origin, pathname) : path_1.default.join(url, pathname);
}
